Skip to content

feat(config): add hostRequirements pre-flight validation#173

Merged
skevetter merged 2 commits into
mainfrom
d226/host-requirements
May 3, 2026
Merged

feat(config): add hostRequirements pre-flight validation#173
skevetter merged 2 commits into
mainfrom
d226/host-requirements

Conversation

@skevetter

@skevetter skevetter commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds ValidateHostRequirements in pkg/devcontainer/config/host_requirements.go that checks CPU count, memory, and storage against host system resources before container creation
  • Uses an injectable HostInfo interface so tests can mock system detection; production implementation reads /proc/meminfo and calls syscall.Statfs
  • Wired into resolveNewContainer in pkg/devcontainer/single.go — logs warnings for unmet requirements without blocking startup (advisory per spec)
  • E2E test validates that hostRequirements is preserved in read-configuration output

Summary by CodeRabbit

  • New Features

    • Added host requirements validation that checks CPU, memory, and storage specifications against the system and alerts users when requirements aren't met.
  • Tests

    • Added end-to-end and unit tests to verify host requirements validation functionality.

@netlify

netlify Bot commented May 3, 2026

Copy link
Copy Markdown

Deploy Preview for devsydev canceled.

Name Link
🔨 Latest commit 11e7dbf
🔍 Latest deploy log https://app.netlify.com/projects/devsydev/deploys/69f731ca3843290008d05fdc

@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@skevetter has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 30 minutes and 32 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 283152ca-18c4-42c7-adad-86d1e367f03c

📥 Commits

Reviewing files that changed from the base of the PR and between d03f814 and 11e7dbf.

📒 Files selected for processing (3)
  • pkg/devcontainer/config/host_requirements_storage_unix.go
  • pkg/devcontainer/config/host_requirements_storage_windows.go
  • pkg/devcontainer/config/host_requirements_system.go
📝 Walkthrough

Walkthrough

This PR introduces host requirements validation for dev containers. It adds core validation logic (ValidateHostRequirements) that checks CPU, memory, and storage requirements against system capacity, system resource discovery (SystemHostInfo), integration into container resolution, comprehensive tests, and a test data file with host requirements configuration.

Changes

Host Requirements Validation Feature

Layer / File(s) Summary
Core Validation & Parsing
pkg/devcontainer/config/host_requirements.go
Introduces ValidateHostRequirements function that checks CPU, memory, and storage requirements against a HostInfo interface; accumulates unmet requirements as warnings. Adds ParseSizeToBytes to parse human-readable size strings (kb/mb/gb/tb) into byte counts.
System Resource Discovery
pkg/devcontainer/config/host_requirements_system.go
Implements SystemHostInfo struct with methods to query actual system metrics: NumCPU() via runtime.NumCPU, TotalMemoryBytes() by parsing /proc/meminfo, and AvailableStorageBytes() via syscall.Statfs.
Container Resolution Integration
pkg/devcontainer/single.go
Calls ValidateHostRequirements with system info and local workspace folder at the start of resolveNewContainer to validate requirements before proceeding with image build/run.
Unit Tests & Test Utilities
pkg/devcontainer/config/host_requirements_test.go
Comprehensive test coverage for ValidateHostRequirements (nil, all met, insufficient CPU/memory/storage, partial, detection errors) and ParseSizeToBytes with valid units and error cases; includes mock HostInfo implementation.
E2E Test & Test Data
e2e/tests/readconfiguration/readconfiguration.go, e2e/tests/readconfiguration/testdata-host-requirements/.devcontainer/devcontainer.json
E2E test case verifies read-configuration command outputs hostRequirements (cpus: 4, memory: "8gb", storage: "32gb"); test data provides sample devcontainer.json with host requirements section.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(config): add hostRequirements pre-flight validation' accurately and concisely describes the main change: introducing pre-flight validation for host requirements configuration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 30 minutes and 32 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the size/l label May 3, 2026
@skevetter
skevetter marked this pull request as ready for review May 3, 2026 10:01
@skevetter
skevetter enabled auto-merge (squash) May 3, 2026 10:01
Validate cpus, memory, and storage requirements from devcontainer.json
against the host system before container creation. Uses an injectable
HostInfo interface for testability. Warnings are logged but do not block
container startup, matching the advisory nature of the spec.
@skevetter
skevetter force-pushed the d226/host-requirements branch from 71f1297 to d03f814 Compare May 3, 2026 11:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/devcontainer/config/host_requirements_system.go (1)

13-16: ⚡ Quick win

WorkspacePath is dead code — remove it.

No method reads s.WorkspacePath; AvailableStorageBytes receives the path as a parameter and single.go always constructs SystemHostInfo{}. The field is misleading and could cause future confusion about where the workspace path is sourced.

🔧 Proposed fix
-// SystemHostInfo provides real system resource information.
-type SystemHostInfo struct {
-	WorkspacePath string
-}
+// SystemHostInfo provides real system resource information.
+type SystemHostInfo struct{}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/devcontainer/config/host_requirements_system.go` around lines 13 - 16,
Remove the dead WorkspacePath field from the SystemHostInfo struct: delete the
WorkspacePath declaration in SystemHostInfo and update any construction or usage
sites that assume it exists (e.g., places that create SystemHostInfo{} in
single.go). Verify AvailableStorageBytes continues to accept the path parameter
and that no methods reference s.WorkspacePath; if any compile errors appear,
remove or replace those references to use the path parameter instead. Run
tests/build to confirm the struct change is safe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/devcontainer/config/host_requirements_system.go`:
- Around line 26-35: This file uses Unix-only APIs (syscall.Statfs and
/proc/meminfo) and needs a build constraint; add a top-line build tag
"//go:build !windows" to host_requirements_system.go and keep the rest
unchanged, and add a new stub file host_requirements_system_windows.go that
provides Windows-safe implementations (matching the same exported types and
methods such as SystemHostInfo.AvailableStorageBytes and any other functions
referenced in this file) returning appropriate zero values and errors or
fallbacks consistent with prepareprobe_windows.go pattern so the package
compiles on Windows.

---

Nitpick comments:
In `@pkg/devcontainer/config/host_requirements_system.go`:
- Around line 13-16: Remove the dead WorkspacePath field from the SystemHostInfo
struct: delete the WorkspacePath declaration in SystemHostInfo and update any
construction or usage sites that assume it exists (e.g., places that create
SystemHostInfo{} in single.go). Verify AvailableStorageBytes continues to accept
the path parameter and that no methods reference s.WorkspacePath; if any compile
errors appear, remove or replace those references to use the path parameter
instead. Run tests/build to confirm the struct change is safe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ec813e3-8139-4dd4-8333-f9f550a30dc3

📥 Commits

Reviewing files that changed from the base of the PR and between 7828ec3 and d03f814.

📒 Files selected for processing (6)
  • e2e/tests/readconfiguration/readconfiguration.go
  • e2e/tests/readconfiguration/testdata-host-requirements/.devcontainer/devcontainer.json
  • pkg/devcontainer/config/host_requirements.go
  • pkg/devcontainer/config/host_requirements_system.go
  • pkg/devcontainer/config/host_requirements_test.go
  • pkg/devcontainer/single.go

Comment on lines +26 to +35
func (s SystemHostInfo) AvailableStorageBytes(path string) (uint64, error) {
if path == "" {
path = "/"
}
var stat syscall.Statfs_t
if err := syscall.Statfs(path, &stat); err != nil {
return 0, fmt.Errorf("statfs %q: %w", path, err)
}
return stat.Bavail * uint64(stat.Bsize), nil //nolint:gosec // Bsize type varies by platform
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for existing build constraints in the config package
rg -n '//go:build' pkg/devcontainer/config/

# Check for any existing Windows-specific stub files
fd -e go . pkg/devcontainer/config/ --exec grep -l 'windows' {}

# Check if there are any CI matrix entries targeting Windows
rg -r 'windows' .github/ 2>/dev/null || true

Repository: devsy-org/devsy

Length of output: 1727


🏁 Script executed:

#!/bin/bash
# Check the actual file content - does it have a build constraint?
head -5 pkg/devcontainer/config/host_requirements_system.go

# Check if there's a Windows stub file for host requirements
fd -e go . pkg/devcontainer/config/ -exec grep -l 'AvailableStorageBytes\|TotalMemoryBytes' {} \;

# Check if Windows is actually a build target
rg -n '//go:build' pkg/devcontainer/config/host_requirements_system.go

# Look for windows stub variant
ls -la pkg/devcontainer/config/ | grep -i host

Repository: devsy-org/devsy

Length of output: 2627


🏁 Script executed:

#!/bin/bash
# Read the complete file to check for build constraints and syscalls
cat -n pkg/devcontainer/config/host_requirements_system.go

# Check if host_requirements.go (parent file) has constraint
head -5 pkg/devcontainer/config/host_requirements.go

# Search for TotalMemoryBytes implementation to find /proc/meminfo
rg -n 'TotalMemoryBytes' pkg/devcontainer/config/

Repository: devsy-org/devsy

Length of output: 2351


🏁 Script executed:

#!/bin/bash
# Check if Windows is a build target in CI
rg -n 'os.*windows|windows.*os' .github/workflows/ 2>/dev/null | head -20

# Check host_requirements.go to see how SystemHostInfo is used
cat -n pkg/devcontainer/config/host_requirements.go | head -40

# Check if there's any conditional compilation around this
rg -B5 -A5 'SystemHostInfo' pkg/devcontainer/config/

Repository: devsy-org/devsy

Length of output: 3148


🏁 Script executed:

#!/bin/bash
# Check main CI workflow for OS matrix
find .github/workflows -name "*.yml" -o -name "*.yaml" | xargs rg -l 'os.*matrix\|windows' 2>/dev/null | head -5

# For each workflow, check the actual matrix
rg -A10 'strategy:' .github/workflows/*.yml 2>/dev/null | head -30

# Check if any main entry point uses SystemHostInfo unconditionally
rg -B3 -A3 'SystemHostInfo{}' pkg/

Repository: devsy-org/devsy

Length of output: 1715


🏁 Script executed:

#!/bin/bash
# Check if SystemHostInfo is instantiated/used in any main packages
rg -n 'SystemHostInfo' pkg/ --type go

# Check what happens in main/entry points for Windows compatibility
rg -n 'main\|init' cmd/ --type go -A5 | head -40

# Check if there's build tag in any importing files
rg -B2 'host_requirements' pkg/ --type go | grep -E '//go:build|SystemHostInfo' | head -20

Repository: devsy-org/devsy

Length of output: 659


🏁 Script executed:

#!/bin/bash
# Check the context where SystemHostInfo is used
cat -n pkg/devcontainer/single.go | sed -n '220,230p'

# Verify Windows build would fail - check if there's any conditional around the instantiation
rg -B10 -A5 'SystemHostInfo\{\}' pkg/devcontainer/single.go

Repository: devsy-org/devsy

Length of output: 1069


Add build constraint to prevent Windows compilation errors — syscall.Statfs and /proc/meminfo are Unix-only.

host_requirements_system.go uses Unix-specific syscalls (syscall.Statfs at line 31 and /proc/meminfo at line 38) but has no //go:build constraint. Since Windows is a supported target (present in CI workflows), this file will fail to compile on Windows. Add //go:build !windows at the top and create a host_requirements_system_windows.go stub implementation following the existing pattern used by prepareprobe.go / prepareprobe_windows.go in the same package.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/devcontainer/config/host_requirements_system.go` around lines 26 - 35,
This file uses Unix-only APIs (syscall.Statfs and /proc/meminfo) and needs a
build constraint; add a top-line build tag "//go:build !windows" to
host_requirements_system.go and keep the rest unchanged, and add a new stub file
host_requirements_system_windows.go that provides Windows-safe implementations
(matching the same exported types and methods such as
SystemHostInfo.AvailableStorageBytes and any other functions referenced in this
file) returning appropriate zero values and errors or fallbacks consistent with
prepareprobe_windows.go pattern so the package compiles on Windows.

Split syscall.Statfs usage into platform-specific files so the package
compiles on Windows where syscall.Statfs_t is undefined.
@skevetter
skevetter merged commit 82cf6b0 into main May 3, 2026
87 of 92 checks passed
@skevetter
skevetter deleted the d226/host-requirements branch May 3, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant